const http = require('http');
const multiparty = require('multiparty');
const path = require('path');
const fs = require('fs-extra');

const UPLOAD_DIR = path.resolve(__dirname, 'qiepian')

// 解析post请求
const resolvePost = (req) => {
  return new Promise((resolve) => {
    let chunk = ''
    
    req.on('data', (data) => {
      chunk += data
    })
    req.on('end', () => {
      resolve(JSON.parse(chunk))
    })
  })
}
// 合并切片
const mergeFileChunks = async(filePath, fileName, size) => {
  const chunkDir = path.resolve(UPLOAD_DIR, `${fileName}-chunks`)
  let chunkPaths = fs.readdirSync(chunkDir)
  
  console.log(chunkPaths);

  chunkPaths.sort((a, b) => a.split('-').pop() - b.split('-').pop())
  
  const arr = chunkPaths.map((chunkPath, index) => {
    return pipeStream(
      path.resolve(chunkDir, chunkPath),
      fs.createWriteStream(filePath, {
        start: index * size,
        end: (index + 1) * size
      })
    )
  })
  await Promise.all(arr)
  
}
// pipeStream
const pipeStream = (path, writeStream) => {
  return new Promise((resolve) => {
    const readStream = fs.createReadStream(path) // 读取流
    readStream.on('end', () => {
      fs.unlinkSync(path) // 删除文件
      resolve()
    })
    readStream.pipe(writeStream)
  })
}



const server = http.createServer(async(req, res) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Headers', '*');
  if (req.method === 'OPTIONS') {
    res.writeHead(200);
    res.end();
    return;
  }

  if (req.url === '/upload') {
    const form = new multiparty.Form();
    form.parse(req, async(err, fields, files) => {
      // console.log(fields, files);
      if (err) {
        console.log(err)
        return 
      }

      const [ file ] = files.file
      const [ fileName ] = fields.fileName
      const [ chunkName ] = fields.chunkName
      // 保存片段
      const chunkDir = path.resolve(UPLOAD_DIR, `${fileName}-chunks`)
      // console.log(chunkDir);
      
      // 判断文件夹是否存在
      if (!fs.existsSync(chunkDir)) {
        await fs.mkdirs(chunkDir)
      }
      fs.move(file.path, `${chunkDir}/${chunkName}`)

      res.end('切片上传成功')
    })
  }

  if (req.url === '/merge') {  // 该合并某一个文件切片了
    const data = await resolvePost(req)
    const { fileName, size } = data
    const filePath = path.resolve(UPLOAD_DIR, fileName)
    // 将 path 路径对应的文件夹下的所有文件合并
    await mergeFileChunks(filePath, fileName, size)
    res.end('文件合并成功')
  }
})

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});